home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / mach / sun3.md / machMon.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  9KB  |  411 lines

  1. /* 
  2.  * machMon.c --
  3.  *
  4.  *     Routines to access the sun prom monitor.
  5.  *
  6.  * Copyright 1985 Regents of the University of California
  7.  * All rights reserved.
  8.  */
  9.  
  10. #ifndef lint
  11. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/mach/sun3.md/machMon.c,v 9.6 91/10/18 01:25:08 dlong Exp $ SPRITE (Berkeley)";
  12. #endif not lint
  13.  
  14. #include "sprite.h"
  15. #include "machMon.h"
  16. #include "machConst.h"
  17. #include "machInt.h"
  18. #include "ctype.h"
  19. #include "mach.h"
  20. #include "vmMach.h"
  21. #include "sys.h"
  22. #ifdef sun4c
  23. #include <string.h>
  24. #endif
  25.  
  26. extern int VmMachGetKernelContext _ARGS_ ((void));
  27. extern void VmMachSetKernelContext _ARGS_((int value));
  28.  
  29. #ifdef sun2
  30. static    int    (*savedNmiVec)() = (int (*)()) 0;
  31. #endif
  32. extern    int    MachMonNmiNop();
  33. static    Boolean    stoppedNMI = FALSE;
  34.  
  35.  
  36. /*
  37.  * ----------------------------------------------------------------------------
  38.  *
  39.  * Mach_MonPutChar --
  40.  *
  41.  *     Call the monitor put character routine
  42.  *
  43.  * Results:
  44.  *     None.
  45.  *
  46.  * Side effects:
  47.  *     None.
  48.  *
  49.  * ----------------------------------------------------------------------------
  50.  */
  51.  
  52. void
  53. Mach_MonPutChar(ch)
  54.     int        ch;
  55. {
  56.     int        oldContext;
  57.  
  58.     if (!isascii(ch)) {
  59.     return;
  60.     }
  61.     DISABLE_INTR();
  62.     oldContext = VmMachGetKernelContext();
  63.     VmMachSetKernelContext(VMMACH_KERN_CONTEXT);
  64.     romVectorPtr->putChar(ch);
  65.     VmMachSetKernelContext(oldContext);
  66.     ENABLE_INTR();
  67. }
  68.  
  69.  
  70. /*
  71.  * ----------------------------------------------------------------------------
  72.  *
  73.  * Mach_MonMayPut --
  74.  *
  75.  *         Call the monitor put may put character routine.  This will return
  76.  *    -1 if it couldn't put out the character.
  77.  *
  78.  * Results:
  79.  *     -1 if couldn't emit the character.
  80.  *
  81.  * Side effects:
  82.  *     None.
  83.  *
  84.  * ----------------------------------------------------------------------------
  85.  */
  86.  
  87. int
  88. Mach_MonMayPut(ch)
  89.     int        ch;
  90. {
  91.     int        oldContext;
  92.     int        retValue;
  93.  
  94.     DISABLE_INTR();
  95.     oldContext = VmMachGetKernelContext();
  96.     VmMachSetKernelContext(VMMACH_KERN_CONTEXT);
  97.     retValue = romVectorPtr->mayPut(ch);
  98.     VmMachSetKernelContext(oldContext);
  99.     ENABLE_INTR();
  100.     return(retValue);
  101. }
  102.  
  103.  
  104. /*
  105.  * ----------------------------------------------------------------------------
  106.  *
  107.  * Mach_MonAbort --
  108.  *
  109.  *         Abort to the monitor.
  110.  *
  111.  * Results:
  112.  *     None.
  113.  *
  114.  * Side effects:
  115.  *     None.
  116.  *
  117.  * ----------------------------------------------------------------------------
  118.  */
  119.  
  120. void
  121. Mach_MonAbort()
  122. {
  123.     int    oldContext;
  124.  
  125.     DISABLE_INTR();
  126.     oldContext = VmMachGetKernelContext();
  127.     VmMachSetKernelContext(VMMACH_KERN_CONTEXT);
  128.     Mach_MonTrap((Address) (romVectorPtr->abortEntry));
  129.     VmMachSetKernelContext(oldContext);
  130.     ENABLE_INTR();
  131. }
  132.  
  133. /*
  134.  * ----------------------------------------------------------------------------
  135.  *
  136.  * Mach_MonReboot --
  137.  *
  138.  *         Reboot the system.
  139.  *
  140.  * Results:
  141.  *     None.
  142.  *
  143.  * Side effects:
  144.  *     System rebooted.
  145.  *
  146.  * ----------------------------------------------------------------------------
  147.  */
  148.  
  149. void
  150. Mach_MonReboot(rebootString)
  151.     char    *rebootString;
  152. {
  153.     DISABLE_INTR();
  154.     (void)VmMachGetKernelContext();
  155.     VmMachSetKernelContext(VMMACH_KERN_CONTEXT);
  156.     Mach_MonStartNmi();
  157.     romVectorPtr->reBoot(rebootString);
  158.     /*
  159.      * If we reach this far something went wrong.
  160.      */
  161.     panic("Mach_MonReboot: Reboot failed (I'm still alive aren't I?)\n");
  162. }
  163.  
  164.  
  165. /*
  166.  * ----------------------------------------------------------------------------
  167.  *
  168.  * Mach_MonStartNmi --
  169.  *
  170.  *    Allow the non-maskable (level 7) interrupts from the clock chip
  171.  *    so the monitor can read the keyboard.
  172.  *
  173.  * Results:
  174.  *     None.
  175.  *
  176.  * Side effects:
  177.  *    Non-maskable interrupts are allowed. On the Sun-2, the 
  178.  *    trap vector is modified. 
  179.  *
  180.  * ----------------------------------------------------------------------------
  181.  */
  182.  
  183. void
  184. Mach_MonStartNmi()
  185. {
  186.     if (stoppedNMI) {
  187. #ifdef sun2
  188.     if (savedNmiVec != 0) {
  189.         machVectorTablePtr->autoVec[6] = savedNmiVec;
  190.     }
  191. #endif
  192. #ifdef sun3
  193.     *Mach_InterruptReg |= MACH_ENABLE_LEVEL7_INTR;
  194. #endif
  195. #ifdef sun4
  196.     *Mach_InterruptReg |= MACH_ENABLE_ALL_INTERRUPTS;
  197. #endif
  198.     stoppedNMI = FALSE;
  199.     }
  200. }
  201.  
  202.  
  203. /*
  204.  * ----------------------------------------------------------------------------
  205.  *
  206.  * Mach_MonStopNmi --
  207.  *
  208.  *     Disallow the non-maskable (level 7) interrupts.  
  209.  *    On the Sun-2, this entails redirecting the interrupt. 
  210.  *    On the Sun-3, the bit in the interrupt register for nmi's is 
  211.  *    turned off.
  212.  *
  213.  * Results:
  214.  *     None.
  215.  *
  216.  * Side effects:
  217.  *    Non-maskable interrupts are disallowed. On the Sun-2, the trap 
  218.  *    vector is modified.
  219.  *
  220.  * ----------------------------------------------------------------------------
  221.  */
  222.  
  223. void
  224. Mach_MonStopNmi()
  225. {
  226.     extern Boolean main_AllowNMI;
  227.  
  228.     /*
  229.      * For debugging purposes, NMI's may need to be enabled.
  230.      * If NMI's are disabled and the kernel goes into an infinite loop, 
  231.      * then getting back to the monitor via L1-A is impossible 
  232.      * However, if NMI's are enabled, level-7 interrupts are caused 
  233.      * and it is possible that characters may be stolen by the monitor.
  234.      * Also, spurious exceptions may occur.
  235.      */
  236.     if (!main_AllowNMI) {
  237.     stoppedNMI = TRUE;
  238. #ifdef sun2
  239.     savedNmiVec = machVectorTablePtr->autoVec[6];
  240.     machVectorTablePtr->autoVec[6] = MachMonNmiNop;
  241. #endif
  242. #ifdef sun3
  243.     *Mach_InterruptReg &= ~MACH_ENABLE_LEVEL7_INTR;
  244. #endif
  245. #ifdef sun4
  246.     *Mach_InterruptReg &= ~MACH_ENABLE_ALL_INTERRUPTS;
  247. #endif
  248.     }
  249. }
  250.  
  251.  
  252. /*
  253.  *----------------------------------------------------------------------
  254.  *
  255.  * Mach_MonTraverseDevTree --
  256.  *
  257.  *    Traverse the device tree, and call the given function
  258.  *    for each node found.  To start at the root of the tree,
  259.  *    the node argument should be set to 0.
  260.  *
  261.  * Results:
  262.  *    None.
  263.  *
  264.  *----------------------------------------------------------------------
  265.  */
  266. #ifdef sun4c
  267. void
  268. Mach_MonTraverseDevTree(node, func, clientData)
  269.     unsigned    int    node;
  270.     int        (*func)();
  271.     Address     clientData;
  272. {
  273.     unsigned    int        newNode;
  274.     char     name[64];
  275.     int        length;
  276.     struct    config_ops    *configPtr;
  277.  
  278.     configPtr = romVectorPtr->v_config_ops;
  279.     if (node == 0) {
  280.     node = configPtr->devr_next(0);
  281.     }
  282.     while (node != 0) {
  283.     length = configPtr->devr_getproplen(node, "name");
  284.     if (length > 0) {
  285.         if (length > sizeof (name)) {
  286.         panic("Mach_MonTraverseDevTree: buffer too small.\n");
  287.         }
  288.         configPtr->devr_getprop(node, "name", name);
  289.         if ((*func)(node, name, clientData))
  290.         return;
  291.     }
  292.     if (newNode = configPtr->devr_child(node)) {
  293.         Mach_MonTraverseDevTree(newNode, func, clientData);
  294.     }
  295.     node = configPtr->devr_next(node);
  296.     }
  297. }
  298.  
  299.  
  300. static int
  301. PrintNode(node, name, clientData)
  302.     unsigned    int    node;
  303.     char        *name;
  304.     void        *clientData;
  305. {
  306.     struct    config_ops    *configPtr;
  307.     char    *prop;
  308.  
  309.     configPtr = romVectorPtr->v_config_ops;
  310.     prop = 0;
  311.     while (1) {
  312.     prop = (char *)configPtr->devr_nextprop(node, prop);
  313.     if (prop && *prop) {
  314.         Mach_MonPrintf("%s: %s\n", name, prop);
  315.     } else {
  316.         break;
  317.     }
  318.     }
  319.     return 0;
  320. }
  321.  
  322. /*
  323.  *----------------------------------------------------------------------
  324.  *
  325.  * Mach_MonTraverseAndPrintDevTree --
  326.  *
  327.  *    Traverse the device tree, and display the attributes
  328.  *    of each node found.
  329.  *
  330.  * Results:
  331.  *    None.
  332.  *
  333.  *----------------------------------------------------------------------
  334.  */
  335.  
  336. void
  337. Mach_MonTraverseAndPrintDevTree()
  338. {
  339.     Mach_MonTraverseDevTree(0, PrintNode, 0);
  340. }
  341.  
  342.  
  343. struct ConfigBuf {
  344.     char    *name;
  345.     char    *attr;
  346.     char    *buf;
  347.     int        buflen;
  348.     int        length;
  349. };
  350.  
  351. static int
  352. CheckNode(node, name, clientData)
  353.     unsigned    int        node;
  354.     char            *name;
  355.     struct    ConfigBuf    *clientData;
  356. {
  357.     int        length;
  358.     struct    config_ops    *configPtr;
  359.  
  360.     configPtr = romVectorPtr->v_config_ops;
  361.     if (strcmp(name, clientData->name) == 0
  362.         || strcmp(clientData->name, "*") == 0) {
  363.     length = configPtr->devr_getproplen(node, clientData->attr);
  364.     if (length <= 0) {
  365.         return 0;
  366.     } else if (length > clientData->buflen) {
  367.         Mach_MonPrintf("Data size (%d) is greater than buffer size (%d)\n",
  368.         length, clientData->buflen);
  369.     } else {
  370.         configPtr->devr_getprop(node, clientData->attr, clientData->buf);
  371.     }
  372.     clientData->length = length;
  373.     return 1;
  374.     }
  375.     return 0;
  376. }
  377.  
  378. /*
  379.  *----------------------------------------------------------------------
  380.  *
  381.  * Mach_MonSearchProm --
  382.  *
  383.  *    Search through the prom devices to find out system attributes.
  384.  *    If attr is given, and name is "*", the info will be retrieved
  385.  *    from the first node with that attribute, otherwise the name
  386.  *    must match exactly.
  387.  *
  388.  * Results:
  389.  *    length of info retrieved.
  390.  *
  391.  *----------------------------------------------------------------------
  392.  */
  393. int
  394. Mach_MonSearchProm(name, attr, buf, buflen)
  395.     char    *name;
  396.     char    *attr;
  397.     char    *buf;
  398.     int        buflen;
  399. {
  400.     struct ConfigBuf data;
  401.  
  402.     data.length = -1;
  403.     data.name = name;
  404.     data.attr = attr;
  405.     data.buf = buf;
  406.     data.buflen = buflen;
  407.     Mach_MonTraverseDevTree(0, CheckNode, (Address)&data);
  408.     return data.length;
  409. }
  410. #endif /* sun4c */
  411.